﻿// Copyright 2009 Mike Geise
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Falcon.Core.Services
{
	using System;
	using System.IO;
	using Falcon.Core.Collections;
	using Falcon.Core.Domain;
	using Falcon.Core.Domain.Repositories;
	using Falcon.Core.Domain.Services;
	using Falcon.Core.Domain.Values;
	using Falcon.Core.Extensions;

	public class UserAlbumPhotoService : IUserAlbumPhotoService
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="UserAlbumPhotoService"/> class.
		/// </summary>
		/// <param name="identityService">The identity service.</param>
		/// <param name="attachmentStoreService">The attachment store service.</param>
		/// <param name="userAlbumService">The user album service.</param>
		/// <param name="userAlbumPhotoRepository">The user album photo repository.</param>
		public UserAlbumPhotoService(
			IIdentityService identityService,
			IAttachmentStoreService attachmentStoreService,
			IUserAlbumService userAlbumService,
			IUserAlbumPhotoRepository userAlbumPhotoRepository)
		{
			this.IdentityService = identityService;
			this.AttachmentStoreService = attachmentStoreService;
			this.UserAlbumService = userAlbumService;
			this.UserAlbumPhotoRepository = userAlbumPhotoRepository;
		}

		/// <summary>
		/// Gets or sets the identity service.
		/// </summary>
		/// <value>The identity service.</value>
		public IIdentityService IdentityService
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets or sets the attachment store service.
		/// </summary>
		/// <value>The attachment store service.</value>
		public IAttachmentStoreService AttachmentStoreService
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets or sets the user album service.
		/// </summary>
		/// <value>The user album service.</value>
		public IUserAlbumService UserAlbumService
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets or sets the user album photo repository.
		/// </summary>
		/// <value>The user album photo repository.</value>
		public IUserAlbumPhotoRepository UserAlbumPhotoRepository
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the user album photo by id.
		/// </summary>
		/// <param name="id">The id.</param>
		/// <returns></returns>
		public UserAlbumPhoto GetById(int id)
		{
			return this.UserAlbumPhotoRepository.GetById(id);
		}

		/// <summary>
		/// Gets all user album photos by specification.
		/// </summary>
		/// <param name="specification">The specification.</param>
		/// <returns></returns>
		public IPagedList<UserAlbumPhoto, UserAlbumPhotoSpecification> GetPaged(UserAlbumPhotoSpecification specification)
		{
			return this.UserAlbumPhotoRepository.GetPaged(specification);
		}

		/// <summary>
		/// Creates the user album photo.
		/// </summary>
		/// <returns></returns>
		public UserAlbumPhoto Create()
		{
			var photo = new UserAlbumPhoto
			{
				Created = DateTime.Now
			};

			return photo;
		}

		/// <summary>
		/// Inserts the specified user album photo.
		/// </summary>
		/// <param name="photo">The photo.</param>
		public void Insert(UserAlbumPhoto photo)
		{
			photo.Validate();

			photo.Slug = photo.Title.Slug();

			this.UserAlbumPhotoRepository.Insert(photo);
		}

		/// <summary>
		/// Inserts the specified user album photo.
		/// </summary>
		/// <param name="value">The value.</param>
		public void Insert(UserAlbumPhotoCreate value)
		{
			value.Validate();

			var identity = IdentityService.Current;

			foreach (var store in value.Attachments)
			{
				var photo = this.Create();

				photo.AlbumId = value.AlbumId;
				photo.UserId = identity.Id;
				photo.Title = Path.GetFileNameWithoutExtension(store.Attachment.FileName);
				photo.Attachment = store.Attachment;

				this.Insert(photo);
				this.AttachmentStoreService.Delete(store, false);
			}

			var preview = this.GetPaged(new UserAlbumPhotoSpecification
			{
				AlbumId = value.AlbumId,
				Page = 1,
				Limit = 1
			}).FirstOrDefault();

			if (preview.Id <= 0)
			{
				return;
			}

			var album = this.UserAlbumService.GetById(value.AlbumId);

			album.Preview = preview;

			this.UserAlbumService.Update(album);
		}

		/// <summary>
		/// Updates the specified user album photo.
		/// </summary>
		/// <param name="photo">The photo.</param>
		public void Update(UserAlbumPhoto photo)
		{
			photo.Validate();

			photo.Slug = photo.Title.Slug();

			this.UserAlbumPhotoRepository.Update(photo);
		}

		/// <summary>
		/// Updates the specified user album photos.
		/// </summary>
		/// <param name="values">The values.</param>
		public void Update(UserAlbumPhotoUpdate[] values)
		{
			if (values == null)
			{
				return;
			}

			for (var i = 0; i < values.Length; i++)
			{
				if (values[i].Id <= 0 || !values[i].Title.HasValue())
				{
					continue;
				}

				var photo = this.GetById(values[i].Id);

				if (!photo.CanUpdate && !photo.CanUpdateAny)
				{
					continue;
				}

				if (photo.Title.Equals(values[i].Title))
				{
					continue;
				}

				photo.Title = values[i].Title;

				this.Update(photo);
			}
		}

		/// <summary>
		/// Deletes the specified user album photo.
		/// </summary>
		/// <param name="photo">The photo.</param>
		public void Delete(UserAlbumPhoto photo)
		{
			this.UserAlbumPhotoRepository.Delete(photo);
		}
	}
}